// Copyright (c) 2010 School of Software, Tsinghua University, Beijing (China)
// All rights reserved.
//
// This file is part of Geoxiom (http://code.google.com/p/geoxiom/); you may 
// redistribute it under the terms of the GNU Lesser General Public License.
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// Author(s) : Kan-Le Shi

#ifndef GEOXIOM_GRAMMAR_WILDCARD_HPP
#define GEOXIOM_GRAMMAR_WILDCARD_HPP

#include "../lex/stream.hpp"

namespace Geoxiom {
namespace Grammar {

typedef std::string PatternType;
static const PatternType all_return_types = "all";

/**
 * @brief This class implements wildcard in template definition of a pattern.
 *        There are two kinds of wildcard, optional and required. It can be
 *        defined in the following syntax.
 *        optional ::= [ return_type_list ]
 *        required ::= < return_type_list > 
 *        array    ::= [ return_type_list ] { min_repeat, max_repeat }
 *                 ::= < return_type_list > { min_repeat, max_repeat }
 *        min_repeat ::= Lex::Element::integer | *
 *        max_repeat ::= Lex::Element::integer | *
 *		  return_type_list ::= Lex::Element::identifier return_type_list | 
 *        The two definitions of the array is the same.
 *        The return type list acceptable pattern types.
 */
typedef class Wildcard {
private:
	typedef Geoxiom::Lex::Stream Stream;

public:
	static const int infinite = 65535;
	int min_repeat;
	int max_repeat;
	int index;
	std::vector<PatternType> filters;

public:
	void operator=(const Wildcard &w) {
		index = w.index;
		min_repeat = w.min_repeat;
		max_repeat = w.max_repeat;
		filters.clear();
		for (std::vector<PatternType>::const_iterator i = w.filters.begin(), 
			 e = w.filters.end(); i != e; i++)
			 filters.push_back(*i);
	}

public:
	Wildcard(const Wildcard &w) : filters() { *this = w; }
	Wildcard() : index(0), min_repeat(0), max_repeat(infinite), filters() { }
	~Wildcard() { }

} *WildcardPtr, *WildcardArray;

}
}

#endif